package cn.iocoder.yudao.module.crm.service.statistics;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.StrUtil;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.module.crm.controller.admin.business.vo.business.CrmBusinessPageReqVO;
import cn.iocoder.yudao.module.crm.controller.admin.customer.vo.customer.CrmCustomerPageReqVO;
import cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.CrmStatisticsIndexReqVO;
import cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.customer.CrmStatisticsCustomerReqVO;
import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessDO;
import cn.iocoder.yudao.module.crm.dal.dataobject.clue.CrmClueDO;
import cn.iocoder.yudao.module.crm.dal.dataobject.contract.CrmContractDO;
import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerDO;
import cn.iocoder.yudao.module.crm.dal.dataobject.permission.CrmPermissionDO;
import cn.iocoder.yudao.module.crm.dal.mysql.business.CrmBusinessMapper;
import cn.iocoder.yudao.module.crm.dal.mysql.clue.CrmClueMapper;
import cn.iocoder.yudao.module.crm.dal.mysql.contract.CrmContractMapper;
import cn.iocoder.yudao.module.crm.dal.mysql.customer.CrmCustomerMapper;
import cn.iocoder.yudao.module.crm.dal.mysql.permission.CrmPermissionMapper;
import cn.iocoder.yudao.module.crm.enums.common.CrmBizTypeEnum;
import cn.iocoder.yudao.module.crm.enums.permission.CrmPermissionLevelEnum;
import cn.iocoder.yudao.module.crm.service.permission.CrmPermissionService;
import cn.iocoder.yudao.module.system.api.dept.DeptApi;
import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO;
import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.List;
import java.util.Objects;

import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;


@Service
public class CrmStatisticsIndexServiceImpl implements CrmStatisticsIndexService {

    @Resource
    private CrmCustomerMapper crmCustomerMapper;

    @Resource
    private CrmPermissionMapper crmPermissionMapper;

    @Resource
    private CrmClueMapper crmClueMapper;

    @Resource
    private CrmBusinessMapper crmBusinessMapper;


    @Resource
    private CrmContractMapper crmContractMapper;

    @Resource
    private DeptApi deptApi;

    @Resource
    private AdminUserApi adminUserApi;

//    @Override
//    public Long getIndexSalesCount(CrmCustomerPageReqVO crmCustomerPageReqVO) {
//        return crmCustomerMapper.selectCount(new LambdaQueryWrapperX<CrmCustomerDO>()
//                .eqIfPresent(CrmCustomerDO::getFollowUpStatus, crmCustomerPageReqVO.getFollowUpStatus())
//                .eqIfPresent(CrmCustomerDO::getOwnerUserId, crmCustomerPageReqVO.getOwnerUserId())
//                .betweenIfPresent(CrmCustomerDO::getCreateTime, crmCustomerPageReqVO.getCreateTime())
//        );
//    }
//
//    @Override
//    public List<CrmBusinessDO> getIndexBusinessList(CrmBusinessPageReqVO crmBusinessPageReqVO) {
//
//        return crmBusinessMapper.selectList(new LambdaQueryWrapperX<CrmBusinessDO>()
//                .eqIfPresent(CrmBusinessDO::getOwnerUserId, crmBusinessPageReqVO.getOwnerUserId())
//                .betweenIfPresent(CrmBusinessDO::getCreateTime, crmBusinessPageReqVO.getCreateTime())
//        );
//    }

    @Override
    public Long getBusinessCount(CrmStatisticsIndexReqVO reqVO) {
        if (CollUtil.isEmpty( reqVO.getUserIds())) {
            return 0L;
        }
        return crmBusinessMapper.selectCount(
                new LambdaQueryWrapperX<CrmBusinessDO>()
                        .in(CrmBusinessDO::getOwnerUserId, reqVO.getUserIds())
                        .betweenIfPresent(CrmBusinessDO::getCreateTime, reqVO.getTime())
        );
    }

    @Override
    public BigDecimal getBusinessAmount(CrmStatisticsIndexReqVO reqVO) {
        if (CollUtil.isEmpty(reqVO.getUserIds())) {
            return BigDecimal.ZERO;
        }

        if (reqVO.getTime().length != 2) {
            return BigDecimal.ZERO;
        }
        return crmBusinessMapper.getBusinessAmount(StrUtil.join(",", reqVO.getUserIds()), reqVO.getTime()[0], reqVO.getTime()[1]);
    }

    @Override
    public Long getContractCount(CrmStatisticsIndexReqVO reqVO) {
        if (CollUtil.isEmpty(reqVO.getUserIds())) {
            return 0L;
        }
        return crmContractMapper.selectCount(
                new LambdaQueryWrapperX<CrmContractDO>()
                        .in(CrmContractDO::getOwnerUserId, reqVO.getUserIds())
                        .betweenIfPresent(CrmContractDO::getCreateTime, reqVO.getTime())
        );
    }

    @Override
    public BigDecimal getContractAmount(CrmStatisticsIndexReqVO reqVO) {
        if (CollUtil.isEmpty(reqVO.getUserIds())) {
            return BigDecimal.ZERO;
        }
        if (Objects.nonNull(reqVO.getTime()) && reqVO.getTime().length == 2) {
            return crmContractMapper.getContractAmount(StrUtil.join(",", reqVO.getUserIds()), reqVO.getTime()[0], reqVO.getTime()[1]);
        } else {
            return BigDecimal.ZERO;
        }
    }

    @Override
    public Long getOwnCustomerCountByUserByDate(CrmStatisticsIndexReqVO reqVO) {
        if (CollUtil.isEmpty( reqVO.getUserIds())) {
            return 0L;
        }
        return crmCustomerMapper.selectCount(
                new LambdaQueryWrapperX<CrmCustomerDO>()
                        .in(CrmCustomerDO::getOwnerUserId, reqVO.getUserIds())
                        .betweenIfPresent(CrmCustomerDO::getOwnerTime, reqVO.getTime())
        );
    }

    @Override
    public Long getPartCustomerCountByUserByDate(CrmStatisticsIndexReqVO reqVO) {
        if (CollUtil.isEmpty( reqVO.getUserIds())) {
            return 0L;
        }
        return crmPermissionMapper.selectCount(
                new LambdaQueryWrapperX<CrmPermissionDO>()
                        .in(CrmPermissionDO::getUserId, reqVO.getUserIds())
                        .eq(CrmPermissionDO::getBizType, CrmBizTypeEnum.CRM_CUSTOMER.getType())
                        .in(CrmPermissionDO::getLevel, ListUtil.toList(CrmPermissionLevelEnum.READ.getLevel(),CrmPermissionLevelEnum.WRITE.getLevel()))
                        .betweenIfPresent(CrmPermissionDO::getCreateTime, reqVO.getTime())
        );
    }

    @Override
    public Long getFollowedCustomerCountByUserByDate(CrmStatisticsIndexReqVO reqVO) {
        if (CollUtil.isEmpty( reqVO.getUserIds())) {
            return 0L;
        }
        return crmCustomerMapper.selectCount(
                new LambdaQueryWrapperX<CrmCustomerDO>()
                        .in(CrmCustomerDO::getOwnerUserId, reqVO.getUserIds())
                        .eq(CrmCustomerDO::getFollowUpStatus, Boolean.TRUE)
                        .betweenIfPresent(CrmCustomerDO::getOwnerTime, reqVO.getTime())
        );
    }

    @Override
    public Long getDealCustomerCountByUserByDate(CrmStatisticsIndexReqVO reqVO) {
        if (CollUtil.isEmpty( reqVO.getUserIds())) {
            return 0L;
        }
        return crmCustomerMapper.selectCount(
                new LambdaQueryWrapperX<CrmCustomerDO>()
                        .in(CrmCustomerDO::getOwnerUserId, reqVO.getUserIds())
                        .eq(CrmCustomerDO::getDealStatus, Boolean.TRUE)
                        .betweenIfPresent(CrmCustomerDO::getOwnerTime, reqVO.getTime())
        );
    }

    @Override
    public Long getOwnClueCountByUserByDate(CrmStatisticsIndexReqVO reqVO) {
        if (CollUtil.isEmpty( reqVO.getUserIds())) {
            return 0L;
        }
        return crmClueMapper.selectCount(
                new LambdaQueryWrapperX<CrmClueDO>()
                        .in(CrmClueDO::getOwnerUserId, reqVO.getUserIds())
                        .betweenIfPresent(CrmClueDO::getOwnerTime, reqVO.getTime())
        );
    }

    @Override
    public Long getPartClueCountByUserByDate(CrmStatisticsIndexReqVO reqVO) {
        if (CollUtil.isEmpty( reqVO.getUserIds())) {
            return 0L;
        }
        return crmPermissionMapper.selectCount(
                new LambdaQueryWrapperX<CrmPermissionDO>()
                        .in(CrmPermissionDO::getUserId, reqVO.getUserIds())
                        .eq(CrmPermissionDO::getBizType, CrmBizTypeEnum.CRM_CLUE.getType())
                        .in(CrmPermissionDO::getLevel, ListUtil.toList(CrmPermissionLevelEnum.READ.getLevel(),CrmPermissionLevelEnum.WRITE.getLevel()))
                        .betweenIfPresent(CrmPermissionDO::getCreateTime, reqVO.getTime())
        );
    }

    @Override
    public Long getFollowedClueCountByUserByDate(CrmStatisticsIndexReqVO reqVO) {
        if (CollUtil.isEmpty( reqVO.getUserIds())) {
            return 0L;
        }
        return crmClueMapper.selectCount(
                new LambdaQueryWrapperX<CrmClueDO>()
                        .in(CrmClueDO::getOwnerUserId, reqVO.getUserIds())
                        .eq(CrmClueDO::getFollowUpStatus, Boolean.TRUE)
                        .betweenIfPresent(CrmClueDO::getOwnerTime, reqVO.getTime())
        );
    }

    @Override
    public Long getTransClueCountByUserByDate(CrmStatisticsIndexReqVO reqVO) {
        if (CollUtil.isEmpty( reqVO.getUserIds())) {
            return 0L;
        }
        return crmClueMapper.selectCount(
                new LambdaQueryWrapperX<CrmClueDO>()
                        .in(CrmClueDO::getOwnerUserId, reqVO.getUserIds())
                        .eq(CrmClueDO::getTransformStatus, Boolean.TRUE)
                        .betweenIfPresent(CrmClueDO::getOwnerTime, reqVO.getTime())
        );
    }

    /**
     * 获取用户编号数组。如果用户编号为空, 则获得部门下的用户编号数组，包括子部门的所有用户编号
     *
     * @param reqVO 请求参数
     * @return 用户编号数组
     */
    @Override
    public List<Long> getUserIds(CrmStatisticsIndexReqVO reqVO) {
        // 情况一：选中某个用户
        if (ObjUtil.isNotNull(reqVO.getUserId())) {
            return ListUtil.of(reqVO.getUserId());
        }
        // 情况二：选中某个部门
        // 2.1 获得部门列表
        List<Long> deptIds = convertList(deptApi.getChildDeptList(reqVO.getDeptId()), DeptRespDTO::getId);
        deptIds.add(reqVO.getDeptId());
        // 2.2 获得用户编号
        return convertList(adminUserApi.getUserListByDeptIds(deptIds), AdminUserRespDTO::getId);
    }
}
